<?php
class databaseControlerMYSQL implements databaseInterface {
    static $db;
    private $resources = array ();
    private $excecutes = array ();
    function connect ($server,$user,$pass,$database) {
        $this->db=@mysql_connect ($server,$user,$pass) or die ('Nao foi possivel conectar-se ao banco de dados.');
        mysql_select_db ($database,$this->db) or die ('Nao foi possivel selecionar o banco de dados desejado.');
        $this->setupTables ();
    }
    /**
     * Este método retorna true se a tabela passada por parâmetro existe no banco de dados
     * ou false se não existir. Para isto, usa como base {@link tabelas}, não prescisando
     * sobregarregar o servidor SQL para esta consulta simples. É ótimo usar para esta classe
     * e subclasses este método para poder validar os resultados com base em suas tabelas.
     * @internal
     * @uses $tables
     * @param string $table
     * @return bool
     */
    public function tableExists ($table) {
        return (in_array($table,$this->tables));
    }
    /**
     * Faz uma lista com todas as tabelas para a classe.
     * Usando este método em seus métodos você terá uma validação direto no inicio de cada método
     * Mas não se esqueça, chame este método toda vez que você adicionar ou remover uma tabela
     * no banco de dados.
     * @return void
     */
    public function setupTables () {
      $tables=$this->excecute ('SHOW TABLES',false);
      while ($this->fetchInto (&$row,$tables,'array','NUM')) {
        $this->tables[]=$row[0];
      }
      return void;
    }
    /**
     * Faz a excecução de uma query
     */
    function excecute ($query,$recordResult=true) {
        $this->excecutes[]=$query;
        $result=mysql_query ($query,$this->db);
        if ($recordResult) $this->resources[]=$result;
        return $result;
    }
    /**
     * Retorna uma query passada anteriormente, muito útil para debug instantâneo
     */
    function getExcecute ($what='LAST') {
        switch ($what) {
            case 'FIRST':
                $return = reset($this->excecutes);
                end($this->resources);
                break;
            case 'LAST':
                $return = end($this->excecutes);
                break;
            default:
                $return = $this->excecutes[(int) $what];
                break;
        }
        return $return;
    }
    /**
     * Pega os resultados gravados no objeto, muitas vezes utilizado pelo
     * método {@link excecute}. Você pode usar em seu parametro uma das três opções:
     * ALL para pegar um array com o histórico completo; LAST para pegar o último
     * result; FIRST para pegar o primeiro resultado; um número inteiro para
     * pegar o result desejado.
     *
     * @param string|int $what
     * @return mixed
     */
    function getResource ($what='LAST') {
        switch ($what) {
            case 'ALL':
              $return=$this->resources;
              break;
            case 'FIRST':
                $return = reset($this->resources);
                end($this->resources);
                break;
            case 'LAST':
                $return = end($this->resources);
                break;
            default:
                $return = $this->resources[(int) $what];
                break;
        }
        return $return;
    }
    function resource (&$resource=null) {
        $resource=($resource?$resource:$this->getResource());
        return $resource;
    }
    /**
     * Esta função adiciona slashes quando necessário em um dado vindo de um $_POST ou $_GET
     * Use-a para prevenir-se de SQL injections
     * <code>
     * $database=new database ('mysql');
     * $sql=sprintf ("SELECT id FROM admins WHERE user=%s AND pass=%s",
     *               $database->quote_smart ($_POST['user']),
     *               $database->quote_smart ($_POST['pass'])
     *       );
     * </code>
     * @param string $value
     * @return string
     */
    function quote_smart($value) {
      if (get_magic_quotes_gpc()) {
        $value = stripslashes($value);
      }
      if (!is_numeric($value)) {
        $value = "'" . mysql_real_escape_string($value) . "'";
      }
      return $value;
    }
    function setPointerOn ($value,$resource=null) {
        $this->resource ($resource);
        mysql_data_seek($resource,$value);
        return void;
    }
    function fetch_object ($resource=null) {
        $this->resource ($resource);
        return mysql_fetch_object($resource);
    }
    function fetch_array ($resource,$type='BOTH') {
        $type=strtoupper($type);
        switch ($type) {
            case 'BOTH':
                $return=mysql_fetch_array($resource,MYSQL_BOTH);
                break;
            case 'NUM':
                $return=mysql_fetch_array($resource,MYSQL_NUM);
                break;
            case 'ASSOC':
                $return=mysql_fetch_array($resource,MYSQL_ASSOC);
                break;
        }
        return $return;
    }
    function fetchInto (&$return, $resource=null,$returnType='object',$returnClass='') {
        $this->resource (&$resource);
        if ($returnType=='object') {
            $return=$this->fetch_object($resource);
        } else if (in_array(strtoupper ($returnClass),array ('BOTH','NUM','ASSOC'))) {
            $return=$this->fetch_array($resource,$returnClass);
        }
        return $return?true:false;
    }
    function num_rows ($resource=null) {
        $this->resource ($resource);
        return mysql_num_rows($resource);
    }
    function num_fields ($resource=null) {
        $this->resource ($resource);
        return mysql_num_fields($resource);
    }
    function affected_rows ($resource=null) {
        $this->resource ($resource);
        return mysql_affected_rows ($resource);
    }
    /**
     * Função mysql_result
     *
     * @param int $linha
     * @param string $coluna
     * @param object|resource $resource
     * @return string|int
     */
    public function result ($linha,$coluna,$resource=null) {
        $this->resource($resource);
        return mysql_result($resource,$linha,$coluna);
    }
    function insert_id () {
        return mysql_insert_id ($this->con);
    }
    function desconecta () {
      mysql_close ($this->db);
      return void;
    }
    function __call ($method,$args) {
        die ("Este metodo ( ".__CLASS__."::$method ) nao existe.");
    }
}
?>